package com.vm.osm.business.task;

import com.vm.osm.business.entity.OsmCheckPlan;
import com.vm.osm.business.entity.OsmCheckPlanInst;
import com.vm.osm.business.service.ICheckPlanService;
import com.vm.osm.business.service.impl.CheckPlanServiceImpl;
import com.vm.osm.business.util.DateFormatUtils;
import com.vm.osm.business.util.UuidUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * Created by chenzui on 2018/4/11.
 */
@Configuration
@EnableScheduling
public class TaskConfig {
    private final Logger LOG = LoggerFactory.getLogger(getClass());

    private ICheckPlanService checkPlanService = new CheckPlanServiceImpl();

    public static long rangeDown = 60*60*24*1000;

    public static long rangeUp = 60*60*48*1000;

    @Scheduled(cron = "0 0 0 * * ?") // 每10分钟执行一次
    public void createLoopOrder() {

        List<OsmCheckPlan> list = checkPlanService.findAll();

        for(OsmCheckPlan checkPlan:list){
            handle(checkPlan);
        }

        LOG.info("getToken定时任务启动");
    }

    private boolean handle(OsmCheckPlan checkPlan) {
        long current = System.currentTimeMillis();
        Integer planType = checkPlan.getPlanType();
        String excuteTimeInfo = checkPlan.getExcuteTmeInfo();
        Calendar calendar = Calendar.getInstance();

        long start = checkPlan.getStartTime().getTime();
            switch (planType){
                //一次性
                case 1:
                    if(current-start >= rangeDown && current-start < rangeUp) {
                        insertInst(checkPlan,null);
                    }
                //按天
                case 2:
                    OsmCheckPlanInst day = checkPlanService.selectFirst(checkPlan.getId());
                    if(day == null){
                        if(current-start >= rangeDown && current-start < rangeUp) {
                            insertInst(checkPlan, DateFormatUtils.formate(new Date(),DateFormatUtils.SPLIT_PATTERN_DATE)+" "+DateFormatUtils.formate(DateFormatUtils.parse(checkPlan.getExcuteStartTime()),DateFormatUtils.SPLIT_PATTERN_TIME));
                        }
                    }else {
                        calendar.setTime(day.getCreateTime());
                        calendar.add(Calendar.DAY_OF_WEEK,checkPlan.getIntervalTime());
                        if(current-calendar.getTime().getTime() >= rangeDown && current-calendar.getTime().getTime() < rangeUp){
                            insertInst(checkPlan, DateFormatUtils.formate(calendar.getTime()
                            ,DateFormatUtils.SPLIT_PATTERN_DATE)+" "+DateFormatUtils.formate(DateFormatUtils.parse(checkPlan.getExcuteStartTime()),DateFormatUtils.SPLIT_PATTERN_TIME));

                        }

                     }
                    ;
                //按周
                case 3:
                    OsmCheckPlanInst week = checkPlanService.selectFirst(checkPlan.getId());
                    if(week == null){

                    }else {
                        calendar.setTime(week.getCreateTime());
                        int index = calendar.get(Calendar.DAY_OF_WEEK);
                        String rule = checkPlan.getExcuteTmeInfo();
                        String[] ruleArr = rule.split(",");
                        List<String> list = new ArrayList();
                        for(int i=0;i<ruleArr.length;i++){
                            list.add(ruleArr[i]);
                        }
                        String next = "";
                        if(list.indexOf(String.valueOf(index)) != list.size()){
                            next = list.get(list.indexOf(String.valueOf(index))+1);
                            calendar.add(Calendar.DAY_OF_WEEK,Integer.valueOf(next));
                        }else {
                            calendar.add(Calendar.DAY_OF_WEEK,Math.abs(Integer.valueOf(list.get(0))-Integer.valueOf(list.get(ruleArr.length))));
                        }



                    }
                    if(current-start >= rangeDown && current-start < rangeUp) {
                        insertInst(checkPlan, DateFormatUtils.formate(new Date(),DateFormatUtils.SPLIT_PATTERN_DATE)+" "+DateFormatUtils.formate(DateFormatUtils.parse(checkPlan.getExcuteStartTime()),DateFormatUtils.SPLIT_PATTERN_TIME));
                    }
                    ;
                //按月
                case 4:
                    OsmCheckPlanInst month = checkPlanService.selectFirst(checkPlan.getId());
                    String rule = checkPlan.getExcuteTmeInfo();
                    String[] ruleArr = rule.split(",");
                    List<String> list = new ArrayList();
                    for(int i=0;i<ruleArr.length;i++){
                        list.add(ruleArr[i]);
                    }
                    if(month == null){
                        calendar.set(Calendar.DAY_OF_MONTH,Integer.valueOf(list.get(0)));

                    }else {
                        Date excuteTime = DateFormatUtils.parse(month.getPlanExcuteTime(),DateFormatUtils.SPLIT_PATTERN_DATETIME);
                        calendar.setTime(excuteTime);
                        int dayOnMonth = calendar.get(Calendar.DAY_OF_MONTH);
                        int index = list.indexOf(String.valueOf(dayOnMonth));

                        calendar.set(Calendar.DAY_OF_MONTH,Integer.valueOf(list.get(index+1)));

                        // TODO: 2018/4/12 月份特殊处理
                    }
                    if(current-calendar.getTime().getTime() >= rangeDown && current-calendar.getTime().getTime() < rangeUp){
                        insertInst(checkPlan, DateFormatUtils.formate(calendar.getTime()
                                ,DateFormatUtils.SPLIT_PATTERN_DATE)+" "+DateFormatUtils.formate(DateFormatUtils.parse(checkPlan.getExcuteStartTime()),DateFormatUtils.SPLIT_PATTERN_TIME));
                    }

                    ;
                //按年
                case 5:
                    OsmCheckPlanInst year = checkPlanService.selectFirst(checkPlan.getId());
                    calendar.setTime(DateFormatUtils.parse(checkPlan.getExcuteStartTime(),DateFormatUtils.SPLIT_PATTERN_DATETIME));

                    if(year != null){
                        calendar.set(Calendar.YEAR,calendar.get(Calendar.YEAR)+1);
                    }
                    if(current-calendar.getTime().getTime() >= rangeDown && current-calendar.getTime().getTime() < rangeUp){
                        insertInst(checkPlan, DateFormatUtils.formate(calendar.getTime()
                                ,DateFormatUtils.SPLIT_PATTERN_DATE)+" "+DateFormatUtils.formate(DateFormatUtils.parse(checkPlan.getExcuteStartTime()),DateFormatUtils.SPLIT_PATTERN_TIME));
                    }
                    ;
            }


        return false;
    }

    private void insertInst(OsmCheckPlan checkPlan,String start){
        OsmCheckPlanInst inst = new OsmCheckPlanInst();
        inst.setAcceptStaffId(checkPlan.getExcuteStaffId());
        inst.setCheckResult("");
        inst.setStatus("5");
        inst.setOrderNbr(new Date().toString());
        inst.setId(UuidUtil.getRandomUuid());
        inst.setCheckPlanId(checkPlan.getId());
        inst.setCheckTitle(checkPlan.getPlanTitle());
        inst.setDispatchTime(new Date());
        inst.setUpdateTime(new Date());
        inst.setAcceptStaffName(checkPlan.getExcuteManName());
        inst.setCreateTime(new Date());
        if(start != null){
            inst.setPlanExcuteTime(start);
        }else {
            inst.setPlanExcuteTime(checkPlan.getExcuteStartTime());

        }
    }

}
//  * 表示所有值. 例如:在分的字段上设置 "*",表示每一分钟都会触发。
//  ? 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的10号触发一个操作，但不关心是周几，所以需要周位置的那个字段设置为"?" 具体设置为 0 0 0 10 * ?
//  - 表示区间。例如 在小时上设置 "10-12",表示 10,11,12点都会触发。
//  , 表示指定多个值，例如在周字段上设置 "MON,WED,FRI" 表示周一，周三和周五触发
//  / 用于递增触发。如在秒上面设置"5/15" 表示从5秒开始，每增15秒触发(5,20,35,50)。在月字段上设置'1/3'所示每月1号开始，每隔三天触发一次。
//  L 表示最后的意思。在日字段设置上，表示当月的最后一天(依据当前月份，如果是二月还会依据是否是润年[leap]), 在周字段上表示星期六，相当于"7"或"SAT"。如果在"L"前加上数字，则表示该数据的最后一个。例如在周字段上设置"6L"这样的格式,则表示“本月最后一个星期五"
//  W 表示离指定日期的最近那个工作日(周一至周五). 例如在日字段上设置"15W"，表示离每月15号最近的那个工作日触发。如果15号正好是周六，则找最近的周五(14号)触发, 如果15号是周未，则找最近的下周一(16号)触发.如果15号正好在工作日(周一至周五)，则就在该天触发。如果指定格式为 "1W",它则表示每月1号往后最近的工作日触发。如果1号正是周六，则将在3号下周一触发。(注，"W"前只能设置具体的数字,不允许区间"-").
//  小提示
//  'L'和 'W'可以一组合使用。如果在日字段上设置"LW",则表示在本月的最后一个工作日触发(一般指发工资 )
//  序号(表示每月的第几个周几)，例如在周字段上设置"6#3"表示在每月的第三个周六.注意如果指定"#5",正好第五周没有周六，则不会触发该配置(用在母亲节和父亲节再合适不过了)